#ifndef V_MATRIX_H
#define V_MATRIX_H

#define PI  3.14159265
#define STACK_CURRENT (stackSize-1)*16

class VMatrix
{
public:
	VMatrix (void);
	~VMatrix (void);

	void Push(void);
	void Pop(void);

	void LoadIdentity (void);
	void LoadMatrix (const float *m);
	void MultMatrix (const float *m);

	void MultVector (const float *v, float *out);

	void Translate (float x, float y, float z);
	void Scale (float x, float y, float z);
	void Rotate (float a, float x, float y, float z);
	
	void LookAt (float ex, float ey, float ez, float cx, float cy, float cz, float ux, float uy, float uz);
	void Frustum (float xmin, float xmax, float ymin, float ymax, float znear, float zfar);
	void Perspective (float fovy, float aspect, float znear, float zfar);

	void GetMatrix (float *m) const;
	void GetMatrixT (float *m) const;
	void GetMatrixIT (float *mit) const;
	void GetMatrixIT3X3(float *mt) const;

	void ScalarMult( float a );
	void ScalarMult3x3( float a );

	void Sum( const VMatrix& mat );

	void normalize (float *x, float *y, float *z);

	float Norm();
	float Determinant();
	
	void Print();
	float Get( int l, int c ) const;
	void Set( int l, int c, float value );

protected:
	float *stack;
	int stackSize;
	int preallocatedStackSize;

	float internalDet( float** a, int n );

	float *scrapMatrix;
	void eraseScrapMatrix (void);

	void crossProduct (float a1, float a2, float a3, float b1, float b2, float b3, float *c1, float *c2, float *c3);
	
};

#endif